﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Mesuro.Equation.Editor {
	/// <summary>
	/// Interaction logic for ExpressionCell.xaml
	/// </summary>
	public partial class ExpressionCell : Grid {

		#region DP: Term
		public static readonly RoutedEvent TermChangedEvent = EventManager.RegisterRoutedEvent( "TermChanged", RoutingStrategy.Bubble, typeof( RoutedEventHandler ), typeof( ExpressionCell ) );
		public event RoutedEventHandler TermChanged {
			add {
				AddHandler( TermChangedEvent, value );
			}
			remove {
				RemoveHandler( TermChangedEvent, value );
			}
		}
		public static readonly DependencyProperty TermProperty = DependencyProperty.RegisterAttached( "Term", typeof( EqTerm ), typeof( ExpressionCell ), new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.AffectsMeasure, TermChangedStatic ) );
		public EqTerm Term {
			get { return (EqTerm)GetValue( TermProperty ); }
			set { SetValue( TermProperty, value ); }
		}
		public static EqTerm GetTerm( ExpressionCell element ) { return (EqTerm)element.GetValue( TermProperty ); }
		public static void SetTerm( ExpressionCell element, EqTerm value ) { element.SetValue( TermProperty, value ); }
		private static void TermChangedStatic( DependencyObject sender, DependencyPropertyChangedEventArgs e ) {
			ExpressionCell cell = sender as ExpressionCell;
			if (cell != null)
				cell.OnTermChanged( (EqTerm)e.OldValue, (EqTerm)e.NewValue );
		}
		#endregion

		public ExpressionCell() {
			InitializeComponent();
		}

		protected void setupOperator( EqOperatorInstance op ) {
			lblCentre.Content = op.Definition.Key; ExpressionCell c;
			switch (op.Definition.Arguments) {
				case EqOperatorArguments.BINARY:
					c = new ExpressionCell() { Term = op.LHS };
					Children.Add( c );
					SetColumn( c, 0 );
					SetRow( c, 1 );
					c = new ExpressionCell() { Term = op.RHS };
					Children.Add( c );
					SetColumn( c, 2 );
					SetRow( c, 1 );
					break;
				case EqOperatorArguments.SUFFIX:
					c = new ExpressionCell() { Term = op.LHS };
					Children.Add( c );
					SetColumn( c, 0 );
					SetRow( c, 1 );
					break;
				case EqOperatorArguments.PREFIX:
					c = new ExpressionCell() { Term = op.RHS };
					Children.Add( c );
					SetColumn( c, 2 );
					SetRow( c, 1 );
					break;
				case EqOperatorArguments.NONE:
					break;
			}
		}

		protected virtual void OnTermChanged( EqTerm oldValue, EqTerm newValue ) {
			Children.Clear();
			if (newValue is EqSymbolInstance) {
				lblCentre.Content = ((EqSymbolInstance)newValue).Key;
			} else if (newValue is EqOperatorInstance) {
				setupOperator( (EqOperatorInstance)newValue );
			}
			RaiseEvent( new RoutedEventArgs( TermChangedEvent ) );
		}
	}
}
